package com.haier.npt;

import java.rmi.ServerException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.haier.npt.common.JsonResult;
import com.haier.npt.exception.BizBaseException;

/**
 * @Description:统一异常处理 
 * @author: lixu
 * @date:   2018年7月18日 上午9:42:13   
 */
@ControllerAdvice
public class GlobalExceptionHandler {

	private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

	/**
	 * 业务异常处理
	 * 
	 * @param ex
	 * @return
	 */
	@ExceptionHandler(value={BizBaseException.class,IllegalArgumentException.class})
	@ResponseStatus(HttpStatus.OK)
	@ResponseBody
	public JsonResult<?> handleBizExp(HttpServletRequest request, Exception ex) {
		logger.error("发生业务异常，请求信息 {} ", this.handleRequestParam(request), ex);
		
		if(ex instanceof BizBaseException){
			BizBaseException exception = (BizBaseException) ex;
			logger.error("发生业务异常，异常信息 {} ", exception.getMessage());
			return JsonResult.error(null==exception.getCode()?500:exception.getCode(), exception.getMessage());
		}
		return JsonResult.error(400);
	}
	
	
	 /**
	  * 
	 * 处理Hibernate Validator消息验证异常
	 * @param @param request
	 * @param @param ex
	 * @param @return    参数  
	 * @return JsonResult<?>    返回类型  
	 * @throws
	  */
	@ExceptionHandler(value={org.springframework.validation.BindException.class})
	@ResponseStatus(HttpStatus.OK)
	@ResponseBody
	public JsonResult<?> handleValidatorExp(HttpServletRequest request, Exception ex){
      logger.error("发生异常，请求信息 {} ", this.handleRequestParam(request), ex);
		StringBuilder sbMessage = new StringBuilder();
		 
		org.springframework.validation.BindException exception = (org.springframework.validation.BindException) ex;
		List<ObjectError> objectErrors = exception.getAllErrors();
		
		for(ObjectError objectError: objectErrors){
			sbMessage.append(objectError.getDefaultMessage()).append(" ;  ");
		}
		sbMessage.deleteCharAt(sbMessage.length()-1);
      logger.error("发生异常，Error信息 {} ", sbMessage.toString());
  		return JsonResult.error(400,"请求无效");  //修改说明：记录日志但不向调用端暴露异常信息
	} 
	
	
	
	
	/**
	 * 包装后的非业务异常
	 * @param request
	 * @param ex
	 * @return
	 */
	@ExceptionHandler(ServerException.class)
	@ResponseStatus(HttpStatus.OK)
	@ResponseBody
	public JsonResult<?> handleServerExp(HttpServletRequest request, Exception ex) {
		logger.error("发生异常，请求信息 {} ", this.handleRequestParam(request), ex);
		return JsonResult.error(500, "服务器错误");  //修改说明：记录日志但不向调用端暴露异常信息
	}

	/**
	 * 非业务异常处理
	 * 
	 * @param ex
	 * @return
	 */
	@ExceptionHandler(Exception.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ResponseBody
	public JsonResult<?> handRuntimeException(HttpServletRequest request, Exception ex) {
		logger.error("服务器错误 ，请求信息 {} ", this.handleRequestParam(request) ,ex);
		return JsonResult.error();  //修改说明：记录日志但不向调用端暴露异常信息
	}
	
	
	/**
	 * 处理请求参数
	 * @param request
	 * @return
	 */
	private Map<String, Object> handleRequestParam(HttpServletRequest request) {
		// 获取所有参数
		Enumeration<?> enu = request.getParameterNames();
		Map<String, Object> map = new HashMap<>();
		while (enu.hasMoreElements()) {
			String paraName = (String) enu.nextElement();
			map.put(paraName, request.getParameter(paraName));
		}
		
		// 获取访问的url
		String url = request.getRequestURL().toString();
		// 获取请求的方法
		String method = request.getMethod();

		map.put("url", url);
		map.put("method", method);
		
		return map ; 
	}
}
